package cn.yuznu.www;

import java.io.*;
import java.net.*;
import java.util.*;
import java.sql.*;

public class ChatServer {
    private ServerSocket server = null;
    private Collection<ClientConn> clients = new ArrayList<>(); // 存储所有客户端连接的集合

    // 构造方法，初始化服务器套接字
    public ChatServer(int port) throws Exception {
        server = new ServerSocket(port);
    }

    // 启动服务器，开始监听和接受客户端连接
    public void startServer() throws Exception {
        System.out.println("服务器启动，等待客户端连接...");
        while (true) {
            Socket socket = server.accept(); // 接受客户端的连接请求
            ClientConn client = new ClientConn(socket); // 为每个客户端连接创建一个ClientConn对象
            clients.add(client); // 添加客户端
            System.out.println("新客户端连接：" + socket.getInetAddress() + ":" + socket.getPort()); // 打印客户端地址和端口
            System.out.println("客户端数量: " + clients.size() + "\n\n"); // 打印当前客户端数量
        }
    }

    // 客户端连接,处理每个客户端的请求
    class ClientConn implements Runnable {
        private Socket socket;

        private DataInputStream dis;
        private DataOutputStream dos;
        private String username;

        // 构造方法，初始化
        public ClientConn(Socket socket) {
            this.socket = socket;
            try {
                dis = new DataInputStream(socket.getInputStream());
                dos = new DataOutputStream(socket.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            new Thread(this).start(); // 为每个客户端连接创建一个新线程
        }

        // 处理客户端请求
        public void run() {
            try {
                String command = dis.readUTF(); // 读取客户端发送的命令
                if ("REGISTER".equals(command)) {
                    String username = dis.readUTF();
                    String password = dis.readUTF();
                    register(username, password); //注册
                } else if ("LOGIN".equals(command)) {
                    String username = dis.readUTF();
                    String password = dis.readUTF();
                    if (login(username, password)) {
                        dos.writeUTF("LOGIN_SUCCESS");
                        this.username = username;
                    } else {
                        dos.writeUTF("LOGIN_FAILURE");
                    }
                }
                String message;
                while ((message = dis.readUTF()) != null) { //广播所有用户发出的消息
                    for (ClientConn client : clients) {
                        if (client != this) {
                            client.dos.writeUTF(this.username + ": " + message);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                clients.remove(this); // 断开连接的时候就在集合中移除
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("客户端断开连接\n");
            }
        }

        // 登录验证方法
        private boolean login(String username, String password) {
            String sql = "SELECT * FROM Users WHERE username = ? AND password = ?";
            try (Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/ChatDB", "root", "1538389602");
                 PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, username);
                pstmt.setString(2, password);

                ResultSet resultSet = pstmt.executeQuery();
                return resultSet.next(); // 如果查询结果不为空，返回true
            } catch (SQLException e) {
                System.out.println("登录时SQL异常：" + e.getMessage());
                e.printStackTrace();
                return false;
            }
        }

        // 注册方法
        private void register(String username, String password) throws IOException {
            String sql = "INSERT INTO Users (username, password) VALUES (?, ?)";
            try (Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/ChatDB", "root", "1538389602");
                 PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, username);
                pstmt.setString(2, password);

                int affectedRows = pstmt.executeUpdate();
                if (affectedRows > 0) {
                    dos.writeUTF("REGISTER_SUCCESS");
                } else {
                    dos.writeUTF("REGISTER_FAILURE");
                }
            } catch (SQLException e) {
                System.out.println("注册时SQL异常：" + e.getMessage());
                e.printStackTrace();
                dos.writeUTF("REGISTER_FAILURE");
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ChatServer cs = new ChatServer(8080);
        cs.startServer();
    }
}